package com.innovation.ic.im.end.data.schedule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.innovation.ic.im.end.base.model.erp9_sqlserver.Erp9Admins;
import com.innovation.ic.im.end.base.model.erp9_sqlserver.Erp9Structures;
import com.innovation.ic.im.end.base.model.im_erp9.Account;
import com.innovation.ic.im.end.base.model.im_erp9.Group;
import com.innovation.ic.im.end.base.model.im_erp9.TreeNode;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.Erp9StructuresStatus;
import com.innovation.ic.im.end.base.pojo.constant.RedisStorage;
import com.innovation.ic.im.end.base.pojo.constant.TreeNodeType;
import com.innovation.ic.im.end.base.pojo.im_erp9.TreeNodePojo;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Configuration
@EnableScheduling
public class ImportTreeNodeTask extends AbstractSchedule {
    private static final Logger log = LoggerFactory.getLogger(ImportTreeNodeTask.class);

    /**
     * 从erp9项目中导入组织机构树形目录的数据
     */
    @Scheduled(cron = "0 10 2 * * ?")
//    @Scheduled(fixedRate = 6000000)
//    @Scheduled(cron = "0 0 10 * * ?")
    private void importTreeNode() {
        try {
            InterProcessMutex lock = new InterProcessMutex(curatorFramework, zookeeperPathDataParamConfig.getImportTreeNode());
            if (lock.acquire(zookeeperParamConfig.getWaitingLockTime(), TimeUnit.SECONDS)) {

                log.info("定时任务开启：从erp9项目中导入组织机构树形目录的数据");

                // 组织结构根目录下的所有节点
                ServiceResult<List<Erp9Structures>> erp9StructuresListServiceResult = erp9StructuresService.findByStatus(Erp9StructuresStatus.AVAILABLE);
                List<TreeNode> treeNodeList = new ArrayList<TreeNode>();
                if (null != erp9StructuresListServiceResult
                        && null != erp9StructuresListServiceResult.getResult()
                        && erp9StructuresListServiceResult.getResult().size() != 0) {
                    List<Erp9Structures> erp9StructuresList = erp9StructuresListServiceResult.getResult();
                    for (int i = 0; i < erp9StructuresList.size(); i++) {
                        Erp9Structures erp9Structures = erp9StructuresList.get(i);
                        TreeNode treeNode = new TreeNode();
                        treeNode.setId(erp9Structures.getId());
                        treeNode.setLabel(erp9Structures.getName());
                        treeNode.setType(TreeNodeType.ORGANIZATION);
                        List<TreeNode> childList = new ArrayList<TreeNode>();

                        // 查找子部门
                        ServiceResult<List<Erp9Structures>> childErp9StructuresListServiceResult = erp9StructuresService.findByFatherId(erp9Structures.getId(), Erp9StructuresStatus.AVAILABLE);
                        if (null != childErp9StructuresListServiceResult
                                && null != childErp9StructuresListServiceResult.getResult()
                                && childErp9StructuresListServiceResult.getResult().size() != 0) {
                            List<Erp9Structures> childErp9StructuresList = childErp9StructuresListServiceResult.getResult();
                            for (int j = 0; j < childErp9StructuresList.size(); j++) {
                                Erp9Structures childErp9Structures = childErp9StructuresList.get(j);
                                TreeNode childTreeNode = new TreeNode();
                                childTreeNode.setId(childErp9Structures.getId());
                                childTreeNode.setLabel(childErp9Structures.getName());
                                childTreeNode.setType(TreeNodeType.ORGANIZATION);
                                childList.add(childTreeNode);
                            }
                        }

                        // 管理员目录放到组织机构下面
                        if (TreeNodeType.ORGANIZATION_NODE_NAME.equals(treeNode.getLabel())) {
                            TreeNode adminTreeNode = new TreeNode();
                            adminTreeNode.setId(TreeNodeType.ADMIN_NODE_ID);
                            adminTreeNode.setLabel(TreeNodeType.ADMIN_NODE_NAME);
                            adminTreeNode.setType(TreeNodeType.ORGANIZATION);
                            childList.add(adminTreeNode);
                        }

                        // 查找部门下的人员
                        ServiceResult<List<Erp9Admins>> childErp9AdminsListServiceResult = erp9AdminsService.findByStructuresId(erp9Structures.getId());
                        if (null != childErp9AdminsListServiceResult
                                && null != childErp9AdminsListServiceResult.getResult()
                                && childErp9AdminsListServiceResult.getResult().size() != 0) {
                            List<Erp9Admins> childErp9AdminsList = childErp9AdminsListServiceResult.getResult();
                            for (int j = 0; j < childErp9AdminsList.size(); j++) {
                                Erp9Admins childErp9Admins = childErp9AdminsList.get(j);
                                TreeNode childTreeNode = new TreeNode();
                                childTreeNode.setId(childErp9Admins.getId());
                                childTreeNode.setLabel(childErp9Admins.getRealName());
                                childTreeNode.setType(TreeNodeType.STAFF);
                                childList.add(childTreeNode);
                            }
                        }

                        treeNode.setChildren(JSONObject.toJSONString(childList));
                        treeNodeList.add(treeNode);
                    }

                }

                // 将不属于任何部门的账号加入到管理员目录下
                ServiceResult<List<Erp9Admins>> erp9AdminsWithEmptyStaffIdListServiceResult = erp9AdminsService.findByStaffIdIsNull();
                if (null != erp9AdminsWithEmptyStaffIdListServiceResult
                        && null != erp9AdminsWithEmptyStaffIdListServiceResult.getResult()
                        && erp9AdminsWithEmptyStaffIdListServiceResult.getResult().size() != 0) {
                    List<Erp9Admins> erp9AdminsWithEmptyStaffIdList = erp9AdminsWithEmptyStaffIdListServiceResult.getResult();
                    TreeNode treeNode = new TreeNode();
                    treeNode.setId(TreeNodeType.ADMIN_NODE_ID);
                    treeNode.setLabel(TreeNodeType.ADMIN_NODE_NAME);
                    treeNode.setType(TreeNodeType.ORGANIZATION);
                    List<TreeNode> childList = new ArrayList<TreeNode>();
                    for (int j = 0; j < erp9AdminsWithEmptyStaffIdList.size(); j++) {
                        Erp9Admins erp9AdminsWithEmptyStaffId = erp9AdminsWithEmptyStaffIdList.get(j);
                        TreeNode treeNodeWithEmptyStaffId = new TreeNode();
                        treeNodeWithEmptyStaffId.setId(erp9AdminsWithEmptyStaffId.getId());
                        treeNodeWithEmptyStaffId.setLabel(erp9AdminsWithEmptyStaffId.getRealName());
                        treeNodeWithEmptyStaffId.setType(TreeNodeType.STAFF);
                        childList.add(treeNodeWithEmptyStaffId);
                    }

                    treeNode.setChildren(JSONObject.toJSONString(childList));
                    treeNodeList.add(treeNode);
                }

                // 删除表中的旧数据
                treeNodeService.truncateTable();
                // 保存记录到数据库
                treeNodeService.saveTreeNodeList(treeNodeList);
                // 保持记录后 将treenode数据放入redist
                this.treeNodeToRedis();
                log.info("定时任务开启：importTreeNode方法执行完成");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 定时导入组织机构后存入redis
     */
    public void treeNodeToRedis() {
        try {
            log.info("treeNodeToRedis方法执行开始");
            //批量删除组织结构缓存数据
            Set<String> strings = redisManager.keysPrefix(RedisStorage.TREE_NODE_PREFIX);
            redisManager.del(strings);

            long l = System.currentTimeMillis();
            List<Group> groups = groupService.groupListAll();
            ServiceResult<List<Account>> listServiceResult = accountService.queryAll();
            List<Account> result = listServiceResult.getResult();
            for (Group group : groups) {
                for (Account account : result) {
                    String key = RedisStorage.TREE_NODE_PREFIX + group.getId() +
                            RedisStorage.UNDERLINE + account.getId() +
                            RedisStorage.UNDERLINE + account.getUsername();
                    //查询数据
                    ServiceResult<TreeNodePojo> serviceResult = treeNodeService.findById(group.getId(), account.getId(), account.getUsername());
                    //更新缓存数据
                    redisManager.set(key, JSON.toJSONString(serviceResult));
                }
            }
            log.info("treeNodeToRedis方法执行完成，耗时:{}ms", System.currentTimeMillis() - l);
        } catch (Exception e) {
            log.error("定时任务添加treeNode数据失败,e:{}", e);
            e.printStackTrace();
        }
    }
}